home *** CD-ROM | disk | FTP | other *** search
/ CD Ware Multimedia 1995 May / cd Ware (Juegos) Epimundo.iso / DOS / C / COP.ZIP / COP.HFM < prev    next >
Encoding:
Text File  |  1992-07-21  |  19.9 KB  |  789 lines

  1. /*
  2.     cop.hfm -- C Object Programming: object
  3.         header template.
  4.  
  5.     (C) Copyright 1992  John W. Small
  6.     All rights reserved
  7.  
  8.     PSW / Power SoftWare
  9.     P.O. Box 10072
  10.     McLean, Virginia 22102 8072 USA
  11.     Voice: (703) 759-3838
  12.  
  13.     
  14.     Always edit a cloned copy of this file.  With
  15.     the case-sensitive flag set and word-only
  16.     flag reset ...
  17.     
  18.     Find and Replace    with something like
  19.     
  20.       structFileName        foobar
  21.       structType            foobar
  22.       structFncPrefix        FB
  23.       
  24.     Edit the remaining text to fully declare your 
  25.     new object.  This file is setup to suggest 
  26.     that your new object inherits three previously 
  27.     declared objects (base1, base2, and base3), 
  28.     the first of which has inherited two more 
  29.     objects.  The third is a virtual base class. 
  30.     All the objects in the hierarchy supposedly 
  31.     have vFt's (Virtual Function Tables) that have
  32.     one or more vF's overridden by the object being 
  33.     declared.  Simply delete those items not 
  34.     pertaining to the new object you're declaring. 
  35.     You should find enough structure here to guide 
  36.     you in expanding this boiler plate for more 
  37.     complicated hierarchies if need be.
  38.  
  39.     Find and replace    with something like
  40.     
  41.       base1FileName            strawber
  42.       base1StructType        Strawberry
  43.       base1StructFncPrefix        SWB
  44.     
  45.     or delete those lines containing unnecessary 
  46.     items.  Complete the find and replace process 
  47.     for base11, base12, base2, and base3 and delete
  48.     any comments you find inappropriate such as 
  49.     this one.
  50. */
  51.  
  52.  
  53.  
  54. /*
  55.     To simulate C++ templates include the following 
  56.     #ifdef statement at this point in your struct's 
  57.     header file.
  58.  
  59. #ifdef CLASS_T
  60. #undef structFileName_H
  61. #endif
  62.  
  63.     Code the header and source files as usual for 
  64.     your struct.  Where the C++ approach would be
  65.     
  66.         template <class CLASS_T>
  67.         struct structType ...
  68.             ... CLASS_T  ...
  69.     
  70.     The COP approach would be:
  71.     
  72.         struct_(structType_CLASS_T)
  73.             { ... CLASS_T ... };
  74.         ... CLASS_T ...
  75.     
  76.         
  77.     To invoke a template instance of your struct 
  78.     instead of the usual C++ approach:
  79.     
  80.         structType<CLASS_T>;
  81.     
  82.     use the following:
  83.     
  84.         #define CLASS_T ???
  85.         #include "structFileName.h"
  86.     
  87.     
  88.     The structFileName.h header file will pull in
  89.     the structFileName.c source file leaving 
  90.     CLASS_T undefined so that the process can be 
  91.     used again.  Another advantage of this approach
  92.     is that both the header and source files can be 
  93.     cloned and CLASS_T globally replaced with the
  94.     correct type by any editor to produce the same
  95.     effect; however, the cloned source files can 
  96.     then be further edited to go beyond template
  97.     adaptibility.
  98. */
  99.  
  100.  
  101. /*
  102.     structFileName.h -- COP object header
  103. */
  104.     
  105. #ifndef structFileName_H
  106. #define structFileName_H
  107.  
  108. #ifndef COP_H
  109. #include "cop.h"
  110. #endif
  111.  
  112. /*
  113.  
  114.     Pointers to types have the same name as the 
  115.     type only the last letter capitalized.  For 
  116.     example if "vf" stands for virtual function 
  117.     then you can infer that "vF" stands for a 
  118.     pointer to a virtual function.  "vFt" stands 
  119.     for a virtual function pointer table so what 
  120.     would you think that "vFT" stands for?  That's 
  121.     right, a pointer to a virtual function pointer 
  122.     table!  This convention is used thoughout.  
  123.     "thiS" is always a pointer to a struct 
  124.     instance.  "thiS" is always assumed to be a 
  125.     valid, non-NULL value unless it is specified as 
  126.     "thiS_0" which means thiS or NULL is expected.  
  127.     Specifying that "thiS" is never NULL allows 
  128.     most member functions to be more efficient.  
  129.     "thiS_0" should only and must be used with the 
  130.     struct_init_???() and struct_destruct() macros
  131.     and your public constructor/destructor macros.
  132.     A NULL value signals a constructor to 
  133.     dynamically allocate memory for the instance
  134.     being constructed.
  135.  
  136. */
  137.  
  138.  
  139. /*
  140.     Include only directly inherited struct
  141.     header files since these in turn will include 
  142.     any header files necessary for their inherited 
  143.     structs!
  144. */ 
  145.  
  146. #ifndef base1FileName_H
  147. #include "base1FileName.h" 
  148. #endif
  149.  
  150. #ifndef base2FileName_H
  151. #include "base2FileName.h"
  152. #endif
  153.  
  154. #ifndef base3FileName_H
  155. #include "base3FileName.h"
  156. #endif
  157.  
  158.  
  159.  
  160. /*
  161.     Forward declare structType's vFt struct if new 
  162.     vF's are introduced at this level.
  163. */
  164.  
  165. struct_vFt_forward(structType);
  166.  
  167.  
  168.  
  169. /*  structType data declarations  */    
  170.  
  171. struct_(structType)  {
  172.  
  173. /*
  174.     All struct data members are considered
  175.     private; access only via member functions
  176.     or macros!
  177. */
  178.  
  179.  
  180. /*  multiple inheritance  */
  181.  
  182.     inherit(base1StructType);
  183.     inherit(base2StructType);
  184.     vbInherit(base3StructType);
  185.  
  186.  
  187. /*
  188.     Add a pointer to the vFt which houses the new 
  189.     vfs introduced at the structType level.
  190. */
  191.  
  192.     vFT_decl(structType);
  193.  
  194.  
  195. /*
  196.     Polymorphic() is required here if any struct 
  197.     in the hierarchy, inclusive, has a vFT!  In 
  198.     other words any struct introducing a vFT and 
  199.     all structs in a hierarchy derived from such a 
  200.     struct are required to have a polymorphic()
  201.     member!  The polymorphic() macro expands to a 
  202.     descendanT pointer.  This allows the virtual 
  203.     functions to adjust their "thiS" pointers to 
  204.     the correct instance struct.  Structs with 
  205.     "descendanT" pointers are said to belong to 
  206.     polymorphic clusters.  Structs with vFTs are 
  207.     said to be polymorphic cluster root structs.  
  208.     Polymorphic clusters can themselves contain 
  209.     other polymorphic clusters, i.e. a partial 
  210.     ordering.
  211. */
  212.  
  213.     polymorphic();
  214.  
  215.  
  216. /*  data members added at structType level  */
  217.  
  218.     ...
  219.  
  220.  
  221. };
  222.  
  223.  
  224.  
  225. /*
  226.     A host structure having a virtual base 
  227.     structure must have a casing structure to hold
  228.     the host and virtual base structures.  Since
  229.     virtual bases are only included once in a 
  230.     heirarchy they can't be contained directly in
  231.     the host structure as with the case with 
  232.     regularly inherited structures.  If the host is
  233.     inherited by yet another structure then that 
  234.     derived structure must have a casing structure
  235.     leaving the intermediate casing structure
  236.     unused.
  237.  
  238.     Only host structures have member functions.
  239.     To use a casing struct thiS pointer with a host
  240.     function you must convert it to the host thiS.
  241.     Use the vbhThiS() macro to convert a casing
  242.     struct thiS pointer to its corresponding
  243.     host struct thiS pointer.  
  244. */
  245.  
  246. struct_vbc(structType) {
  247.     vbh_decl(structType);
  248.     vb_decl(base3StructType);
  249. /*
  250.     A casing structure has only one host structure
  251.     and one or more virtual base structures.
  252. */
  253. };
  254.  
  255.  
  256.  
  257.  
  258. /*
  259.     Define typecasts to/from structType.  
  260.     Follow this chaining format even if you don't 
  261.     have an immediate use for some of the macros.  
  262.     By following this format your structs will be 
  263.     extensible later.  In fact the macros here 
  264.     assume that the format was followed by the 
  265.     base1Struct and call its macros to reach 
  266.     base11 and base12 which are supposedly 
  267.     inherited by base1.
  268.  
  269.     Base1 is assumed to be a polymorphic focus that
  270.     processing will center around, hence the
  271.     polyBaseThiS_0_decl() function declaration.
  272.     The corresponding function definition in 
  273.     cop.cfm allows the upcasting of "thiS_0"
  274.     pointers to the polymorphic root on the fly
  275.     which is unattainable with nested macros.  The
  276.     corresponding polyBaseThiS_0_def() expansion
  277.     in cop.cfm assumes the previous definition of
  278.     structFncPrefix_base1StructTypeThiS() macro.
  279.     It should well known at the current level what
  280.     polymorphic root code future derived instances
  281.     will need to be implicitly upcasted to an thus
  282.     only those casts need to be declared with
  283.     polyBaseThiS_0_decl().
  284. */
  285.  
  286. #define structFncPrefix_base1StructTypeThiS(thiS)  \
  287.     baseThiS(thiS,base1StructType)
  288. polyBaseThiS_0_decl(structFncPrefix,
  289.     base1StructType,structType);
  290. #define structFncPrefix_base11StructTypeThiS(thiS)  \
  291.     base1StructFncPrefix_base11StructTypeThiS  \
  292.     (baseThiS(thiS,base1StructType))
  293. #define structFncPrefix_base12StructTypeThiS(thiS)  \
  294.     base1StructFncPrefix_base12StructTypeThiS  \
  295.     (baseThiS(thiS,base1StructType))
  296. #define structFncPrefix_base2StructTypeThiS(thiS)  \
  297.     baseThiS(thiS,base2StructType)
  298. #define structFncPrefix_base3StructTypeThiS(thiS)  \
  299.     vbThiS(thiS,base3StructType)
  300. #define base1StructFncPrefix_structTypeThiS(thiS)  \
  301.     derivedThiS(thiS,structType)
  302. #define base11StructFncPrefix_structTypeThiS(thiS)  \
  303.     base1StructFncPrefix_structTypeThiS  \
  304.     (base11StructFncPrefix_base1StructTypeThiS  \
  305.     (thiS))    
  306. #define base12StructFncPrefix_structTypeThiS(thiS)  \
  307.     base1StructFncPrefix_structTypeThiS  \
  308.     (base12StructFncPrefix_base1StructTypeThiS  \
  309.     (thiS))
  310. #define base2StructFncPrefix_structTypeThiS(thiS)  \
  311.     derivedThiS(thiS,structType)
  312. #define base3StructFncPrefix_structTypeThiS(thiS)  \
  313.     vbDerivedThiS(thiS,structType)
  314.  
  315.  
  316.  
  317. /*  Declare structType's static members  */
  318.  
  319. struct_static(structType)  {
  320.  
  321.     int StaticVariable;
  322.     ...
  323.  
  324. };
  325.  
  326.  
  327.  
  328. /*
  329.     Declare structType's vFt struct for new vF's 
  330.     introduced at the structType level.
  331. */
  332.  
  333. struct_vFt(structType)  {
  334.  
  335.     vF_decl(void,dummyVf,(structType * thiS, ...));
  336.  
  337.  
  338. /*
  339.     If any base struct in the hierarchy has a 
  340.     virtual destructor then override that 
  341.     destructor below instead of starting a new 
  342.     polymorphic root here!  You must always 
  343.     override ALL virtual destructors inherited 
  344.     regardless of which branch of the hierarchy 
  345.     they reside!  Thus once a virtual destructor 
  346.     is introduced into a hierarchy, descendants' 
  347.     destructors can only be virtual overrides! 
  348.     Be sure to always use the exact formal 
  349.     parameter list shown below.
  350. */
  351.  
  352.       vF_decl(void, destruct,(structType * thiS,
  353.         unsigned nobj, int malloced));
  354.  
  355. };
  356.  
  357.  
  358.  
  359. /*  Declare structType's default vFt for new vF's  */
  360.  
  361. vFt_decl(structType,structType);
  362.  
  363.  
  364. /*  Declare vf's for structType's default vFt  */
  365.  
  366. vf_decl(void,structFncPrefix,structFncPrefix,
  367.     dummyVf,(structType * thiS, ...));
  368. vf_decl(void,structFncPrefix,structFncPrefix,
  369.     destruct,(structType * thiS, unsigned nobj,
  370.     int malloced));
  371. /*
  372.     In practice you'll find it easy to copy the 
  373.     vF_decl()s in struct_vFt() above and 
  374.     edit them to read vf_decl().  Of course you'll 
  375.     need to add the overriding fnc and spawning 
  376.     fnc prefix parameters.
  377. */
  378.  
  379.  
  380. /*
  381.     Declare structType's overriding vFt's for all
  382.     BaseStructs within inherited hierarchy having
  383.     vf's overridden at structType level.  You must
  384.     always override all virtual destructors
  385.     inherited regardless of which branch of the 
  386.     hierarchy they reside!    Once a virtual 
  387.     destructor is introduced into a hierarchy,
  388.     descendants' destructors can only be virtual
  389.     overrides!
  390. */
  391.  
  392. vFt_decl(structType,base1StructType);
  393.  
  394. vf_decl(base1StructType *,
  395.     structFncPrefix,base1StructFncPrefix,
  396.     vfbase1,(base1StructType * thiS, ...));
  397. /*
  398.     Repeat the vf_decl() macro for all base1 vfs 
  399.     that are overriden at the structType level.  
  400.     Note that the overriding vfs retain the thiS 
  401.     pointer to the original level struct at which 
  402.     they were introduced!  In practice you'll find 
  403.     it easiest to copy the vf_decl()s from their 
  404.     respective base struct headers and edit the 
  405.     overriding fnc prefixes to read 
  406.     structFncPrefix.  Then simply delete those 
  407.     lines with vfs that you are not overriding!
  408. */
  409.     
  410.     
  411. vFt_decl(structType,base11StructType);
  412.  
  413. vf_decl(void,structFncPrefix,base11StructFncPrefix,
  414.     vfbase11,(base11StructType * thiS, ...));
  415.  
  416.  
  417. vFt_decl(structType,base12StructType);
  418.  
  419. vf_decl(int,structFncPrefix,base12StructFncPrefix,
  420.     vfbase12,(base12StructType * thiS, ...));
  421.  
  422.  
  423. vFt_decl(structType,base2StructType);
  424.  
  425. vf_decl(int,structFncPrefix,base2StructFncPrefix,
  426.     vfbase2,(base2StructType * thiS, ...));
  427.  
  428. vFt_decl(structType,base3StructType);
  429.  
  430. vf_decl(int,structFncPrefix,base3StructFncPrefix,
  431.     vfbase3,(base3StructType * thiS, ...));
  432.  
  433.  
  434. /*
  435.     Declare structType's protected constructors 
  436.     and destructors.  Be sure to follow this 
  437.     format even for simple objects to insure that
  438.     they are extensible -- you'll begin to see the
  439.     reasoning once your hierarchies begin to grow
  440.     and especially when you attempt to make 
  441.     objects persistent!
  442. */
  443.  
  444. struct_initVFTs_decl(structFncPrefix,
  445.     (structType * thiS, 
  446.     void * descendanT_0
  447.     , vFT_0_decl(structType)
  448. /*
  449.     All base structs with vFTs need    to be 
  450.     initialized thus require their specific formal 
  451.     parameter.  A null pointer when passed as a 
  452.     actual parameter indicates to use the default 
  453.     vFT in question (see struct_initVFTs_def).
  454. */
  455.     , vFT_0_decl(base1StructType)
  456.     , vFT_0_decl(base11StructType)
  457.     , vFT_0_decl(base12StructType)
  458.     , vFT_0_decl(base2StructType)
  459. /*
  460.     Since a virtual base struct is not contained
  461.     within the host struct you must tell it where
  462.     it does reside with a pointer.  The pointer
  463.     points to the virtual base that is in a    casing
  464.     struct.
  465. */
  466.     , vbThiS_decl(base3StructType)
  467. /*
  468.     If the virtual base is polymorphic then its 
  469.     descendant pointer is handled specially.  If
  470.     the virtual base is inherited through more then
  471.     one branch the descendant pointer must point 
  472.     the most derived struct joining all branches.
  473.     If a casing struct is inherited then that 
  474.     becomes the lowest joint as far as the virtual
  475.     base descendant pointer is concerned.  If NULL
  476.     is passed then this indicates that a regular
  477.     descendant chain is in effect.  Remember the
  478.     virtual function definition must embody the 
  479.     knowledge to read these chains as necessary.
  480. */
  481.     , vbDescendanT_0_decl(base3StructType)
  482.     , vFT_0_decl(base3StructType)
  483.     ));
  484.  
  485. /*
  486.     Make sure you have enough closing parentheses
  487.     above, typically 3.  It is very hard to find
  488.     the bug reported by most C preprocessors if 
  489.     you don't!
  490. */
  491.  
  492.  
  493. /*
  494.     Define the following two heap management
  495.     macros as shown.  If a special heap is to be
  496.     used to instanciate structures, here is the 
  497.     place to redefine them.  This corresponds to
  498.     C++ class overloading of the new and delete
  499.     operators.  To globally overloaded new and
  500.     delete, define MALLOC and FREE macros ahead
  501.     of the inclusion of the cop.h header file or
  502.     edit the MALLOC and FREE macros in cop.h.
  503. */
  504.  
  505. #define structFncPrefix_malloc(nobj)  \
  506.     MALLOC(sizeof(structType)*nobj)
  507.  
  508. #define structFncPrefix_free(thiS)  FREE(thiS)
  509.  
  510.  
  511. /*
  512.     This protected constructor is required of all
  513.     cop structures to allow extensibility.  The
  514.     protected constructor's thiS_0 parameter 
  515.     allows for dynamic allocation.  If thiS_0 is
  516.     NULL then the constructor first allocates the 
  517.     instance.  For a derived structure thiS_0
  518.     may be NULL at the level of instanciation but
  519.     for intermediate level constructor calls 
  520.     thiS_0 is never NULL!  The nobj parameter
  521.     allows for the construction of vectors of
  522.     instances.  For intermediate constructors nobj
  523.     is always 1 (see cop.cfm) since instance is
  524.     completely constructed before moving on to the
  525.     next instance in the vector.  Notice here the
  526.     parameter to indicate the location of the 
  527.     virtual base3 struct.
  528. */
  529.     
  530. struct_init_decl(structType,structFncPrefix,_,
  531.     (structType * thiS_0
  532.         , unsigned nobj
  533.         , vbThiS_decl(base3StructType)
  534.         , ... initializers
  535.     ));
  536.  
  537. /*
  538.     If you need more than one constructor then 
  539.     repeat the struct_inita_decl() macro above
  540.     with an overloaded suffix parameter and the 
  541.     appropriate initialization parameters.
  542. */
  543.  
  544.  
  545. /*
  546.     This protected destructor is required of all
  547.     cop structures to insure extensibility.  See
  548.     comment above struct_init_decl().
  549. */
  550.  
  551. struct_destruct_decl(structType,structFncPrefix);
  552.  
  553.  
  554. /*
  555.     Define structType's public
  556.     constructors and destructors.
  557. */
  558.  
  559. #define structFncPrefix_init(thiS_0,nobj, ...)  \
  560.     struct_init(structFncPrefix,_,  \
  561.     (thiS_0,nobj, ...))
  562. /* besure to put parentheses around actualParams! */
  563. #define structFncPrefix_init_default(thiS_0)  \
  564.     structFncPrefix_init(thiS_0,1, ...)
  565. #define structFncPrefix_new(nobj,...)  \
  566.     structFncPrefix_init((structType *)0,nobj,  \
  567.     ...)
  568. #define structFncPrefix_new_default()  \
  569.     structFncPrefix_new(1,...)
  570. #define structFncPrefix_destruct(thiS,nobj)
  571. /*
  572.   Define the structFncPrefix_destruct macro as
  573.   follows:
  574.  
  575.   If a virtual destructor is in use
  576.     if the virtual destructor originates at this level
  577.  
  578.     vf_runTimeBind(thiS,destruct,(thiS,nobj,0))
  579.  
  580.     else
  581.  
  582.     base?StructFncPrefix_destruct  \
  583.       (structFncPrefix_base?StructTypeThiS  \
  584.       (thiS),nobj)
  585.     //any immediate base with a virtual destructor
  586.  
  587.   else
  588.  
  589.     struct_destruct(structFncPrefix,thiS,nobj,0)
  590. */
  591. #define structFncPrefix_delete(thiS_0,nobj) 
  592. /*
  593.   Define the structFncPrefix_delete macro as
  594.   follows:
  595.  
  596.   If a virtual destructor is in use
  597.     if the virtual destructor originates at this level
  598.  
  599.     if (thiS_0) vf_runTimeBind(thiS_0,\
  600.         destruct,(thiS_0,nobj,1)); else
  601.  
  602.     else
  603.  
  604.     if (thiS_0) base?StructFncPrefix_delete  \
  605.       (structFncPrefix_base?StructTypeThiS  \
  606.       (thiS_0),nobj); else
  607.     //any immediate base with a virtual destructor
  608.  
  609.   else
  610.  
  611.     struct_destruct(structFncPrefix,thiS_0,nobj,1)
  612. */
  613.  
  614.  
  615. /*
  616.     Declare structType member functions and
  617.     define  structType member macros below.
  618.     Private members should be prefixed with an 
  619.     additional "PV_" and protected members with 
  620.     "PT_".  It is good practice to declare the 
  621.     base struct promoted member functions first 
  622.     followed by the current level member 
  623.     functions.  Remember, adherence to strict 
  624.     programming style guidelines is the key to 
  625.     successfully managing the complexities of OOP
  626.     in a non OOP language!
  627. */
  628.  
  629.  
  630. /*
  631.     Base members should be promoted to the current
  632.     structType level as shown below.  This way 
  633.     only current level functions are used on 
  634.     current level instances.  
  635. */
  636.  
  637. #define structFncPrefix_base1fnc(thiS, ...)  \
  638.     base1StructFncPrefix_base1fnc  \
  639.     (structFncPrefix_base1StructTypeThiS(thiS),  \
  640.     ...)
  641.  
  642. /*
  643.     To invoke a virtual function at the current 
  644.     level use the vf_runTimeBind() macro.  All the 
  645.     vf declarations above were for the actual 
  646.     functions.  You'll want to present an
  647.     interface to the user that makes the run time 
  648.     binding transparent.
  649. */
  650.  
  651. #define structFncPrefix_dummyVf(thiS, ...)  \
  652.     vf_runTimeBind(thiS,dummyVf,(thiS, ...));
  653.     
  654. /*
  655.     To invoke a virtual function originating at a 
  656.     base level simply promote the base member 
  657.     interface to the current level, e.g.
  658. */
  659.  
  660. #define structFncPrefix_vfbase1(thiS, ...)  \
  661.     base1StructFncPrefix_vfbase1  \
  662.     (structFncPrefix_base1StructTypeThiS(thiS),  \
  663.     ...)
  664.  
  665.  
  666. /*
  667.   The exact logic for declaring/defining member 
  668.   functions is as follows:
  669.  
  670.   If the function is virtual
  671.     if the function originates in a vFt at this level
  672.     
  673.         #define structFncPrefix_fncName(thiS, ...)  \
  674.       vf_runTimeBind(thiS,fncName,(thiS, ...))
  675.     
  676.     else
  677.     
  678.         #define structFncPrefix_fncName(thiS, ...)  \
  679.       base?StructFncPrefix_fncName  \
  680.       (structFncPrefix_base?StructTypeThiS(thiS),\
  681.       ...)
  682.     // Don't define this case if it doesn't make
  683.     // sense to use the structType level for
  684.     // polymorphic processing instead of the
  685.     // polymorphic root itself.  Destructors are
  686.     // different since you never know what level
  687.     // you may want to call a virtual destructor
  688.     // from.
  689.  
  690.   else
  691.  
  692.       extern structFncPrefix_fncName
  693.         (structType * thiS, ...);
  694. */
  695.  
  696.  
  697. /*
  698.     Use the following convention to translate C++
  699.     overloaded operators
  700.     
  701.     class member operators become:
  702.     
  703.         structFncPrefix_op_???
  704.             (structType * thiS, ...)
  705.     
  706.     and non member operators become:
  707.     
  708.         op_???(...)
  709.     
  710.     where:
  711.     
  712.     operator    ???
  713.         
  714.     []        subscript
  715.     ()        fncCall
  716.     ->        select
  717.     ++        inc
  718.     --        dec
  719.     &        addr
  720.     *        indirect
  721.     +        uPlus
  722.     -        uMinus
  723.     ~        complement
  724.     !        negate
  725.     sizeof        sizeof
  726.     *        mult
  727.     /        div
  728.     %        rmdr
  729.     +        plus
  730.     -        minus
  731.     <<        LShift
  732.     >>        RShift
  733.     <        LT
  734.     >        GT
  735.     <=        LE
  736.     >=        GE
  737.     ==        EQ
  738.     !=        NE
  739.     ^        bwXOR
  740.     &        bwAND
  741.     |        bwOR
  742.     &&        AND
  743.     ||        OR
  744.     =        asg
  745.     *=        asgProd
  746.     /=        asgQuot
  747.     %=        asgRmdr
  748.     +=        asgSum
  749.     -=        asgDiff
  750.     <<=        asgLShift
  751.     >>=        asgRShift
  752.     &=        asgBwAND
  753.     ^=        asgBwXOR
  754.     |=        asgBwOR
  755.     ,        comma
  756. */
  757.     
  758.  
  759. /*
  760.     Don't forget static data member access!  The 
  761.     conditional expression below guarantees that
  762.     we don't have an lvalue so the macro can't be 
  763.     wrongly used.  Optimization should discard the 
  764.     test leaving only the expression we want.
  765. */
  766.  
  767. #define structFncPrefix_getStaticVariable()  \
  768.     (1? static_ref(structType,  \
  769.     StaticVariable) : 1)
  770.  
  771.  
  772.  
  773.  
  774.  
  775. #endif  /*  structFileName_H  */
  776.  
  777.  
  778. /*
  779.  
  780.     If you are simulating C++ templates above 
  781.     include the following.
  782.     
  783. #ifdef CLASS_T
  784. #include "structFileName.c"
  785. #undef CLASS_T
  786. #endif
  787.  
  788. */
  789.